from api.database import db
from flask import Flask, jsonify
from flask_jwt_extended import JWTManager
from flask_marshmallow import Marshmallow
from flask_cors import CORS
from flask_migrate import Migrate
from api.config import Config
from api.apps.utils.logging_config import setup_logging

# 初始化扩展
cors = CORS()
migrate = Migrate()
marshmallow = Marshmallow()
jwt = JWTManager()
app = Flask(__name__, static_folder='../../dist', template_folder='../../dist', static_url_path='/')


def create_app(config_class=Config):
  """
  创建 Flask 应用的工厂函数。
  :param config_class: 配置类，默认为 Config
  :return: Flask 应用实例
  """

  app.config.from_object(config_class)

  # 初始化扩展
  with app.app_context():
    db.init_app(app)
    migrate.init_app(app, db)
    cors.init_app(app, supports_credentials=True)
    marshmallow.init_app(app)
    jwt.init_app(app)

  # 配置日志
  configure_logging()

  # 注册错误处理器
  register_error_handlers(app)

  # 注册蓝图
  register_blueprints(app)

  return app


def configure_logging():
  logger = setup_logging()
  logger.info('Starting the application...')


def register_error_handlers(app):
  """
  注册全局错误处理器。
  :param app: Flask 应用实例
  """

  @app.errorhandler(404)
  def not_found_error(error):
    app.logger.error(f'404 Error: {error}')
    return jsonify({"error": "Resource not found"}), 404

  @app.errorhandler(500)
  def internal_error(error):
    app.logger.error(f'500 Error: {error}')
    return jsonify({"error": "Internal server error"}), 500


def register_blueprints(app):
  """
  注册蓝图到 Flask 应用。
  :param app: Flask 应用实例
  """
  from flask_swagger_ui import get_swaggerui_blueprint
  from api.apps.author import author_bp
  from api.apps.books import books_bp
  from api.apps.users import users_bp

  app.register_blueprint(author_bp, url_prefix='/api/author')
  app.register_blueprint(books_bp, url_prefix='/api/books')
  app.register_blueprint(users_bp, url_prefix='/api/users')

  # 创建 Swagger UI 蓝图
  swagger_url = '/api/docs'
  # api_url = 'http://petstore.swagger.io/v2/swagger.json'
  swagger_ui_blueprint = get_swaggerui_blueprint(
    swagger_url,  # Swagger UI 的访问路径
    '/api/spec',  # API 文档的路径
    config={  # Swagger UI 配置
      'app_name': "Flask API Docs"  # 应用名称
    }
  )
  app.register_blueprint(swagger_ui_blueprint, url_prefix=swagger_url)
